# -*- coding: utf-8 -*-
# 图形用户界面模块

import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from core.mobaxterm import MobaXtermGenerator
from core.securecrt import SecureCRTGenerator
from core.xshell import XShellGenerator
from utils.template import get_template_path, download_template, create_default_template, create_machine_list_template
from core.data_loader import get_excel_sheet_names, validate_excel_sheet

class SessionGeneratorGUI:
    """会话生成器图形用户界面"""
    
    def __init__(self, root):
        self.root = root
        self.root.title("SSH客户端会话生成工具")
        self.root.geometry("650x450")
        
        # 变量初始化
        self.client_type = tk.StringVar(value="mobaxterm")
        self.data_file = tk.StringVar()
        self.sheet_name = tk.StringVar(value="Sheet1")
        self.output_dir = tk.StringVar(value=os.getcwd())
        self.template_file = tk.StringVar()
        
        # 创建UI
        self._create_ui()
    
    def _create_ui(self):
        """创建用户界面"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 客户端类型选择
        ttk.Label(main_frame, text="SSH客户端类型:").grid(row=0, column=0, sticky=tk.W, pady=5)
        client_types = ["mobaxterm", "securecrt", "xshell"]
        client_combo = ttk.Combobox(main_frame, textvariable=self.client_type, values=client_types, state="readonly")
        client_combo.grid(row=0, column=1, sticky=tk.W+tk.E, pady=5)
        client_combo.bind("<<ComboboxSelected>>", self._update_template_path)
        
        # 机器列表文件区域
        data_frame = ttk.LabelFrame(main_frame, text="机器列表")
        data_frame.grid(row=1, column=0, columnspan=3, sticky=tk.W+tk.E, pady=10)
        
        # 第一行：机器列表模板生成
        ttk.Label(data_frame, text="机器列表模板:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
        template_btn_frame = ttk.Frame(data_frame)
        template_btn_frame.grid(row=0, column=1, columnspan=2, sticky=tk.W, padx=5, pady=5)
        
        ttk.Button(template_btn_frame, text="生成Excel模板", 
                   command=lambda: self._create_machine_list("xlsx")).pack(side=tk.LEFT, padx=5)
        ttk.Button(template_btn_frame, text="生成CSV模板", 
                   command=lambda: self._create_machine_list("csv")).pack(side=tk.LEFT, padx=5)
        
        # 第二行：机器列表文件路径和浏览按钮
        ttk.Label(data_frame, text="机器列表文件:").grid(row=1, column=0, sticky=tk.W, padx=5, pady=5)
        ttk.Entry(data_frame, textvariable=self.data_file, width=40).grid(row=1, column=1, sticky=tk.W+tk.E, padx=5, pady=5)
        ttk.Button(data_frame, text="浏览...", command=self._browse_data_file).grid(row=1, column=2, padx=5, pady=5)
        
        # 第三行：Excel表格名
        ttk.Label(data_frame, text="表格名 (Excel):").grid(row=2, column=0, sticky=tk.W, padx=5, pady=5)
        ttk.Entry(data_frame, textvariable=self.sheet_name).grid(row=2, column=1, sticky=tk.W, padx=5, pady=5)
        
        # 输出目录
        ttk.Label(main_frame, text="输出目录:").grid(row=2, column=0, sticky=tk.W, pady=5)
        ttk.Entry(main_frame, textvariable=self.output_dir).grid(row=2, column=1, sticky=tk.W+tk.E, pady=5)
        ttk.Button(main_frame, text="浏览...", command=self._browse_output_dir).grid(row=2, column=2, pady=5)
        
        # 模板文件 - 使用内置模板，保留该行以显示当前使用的模板
        ttk.Label(main_frame, text="模板文件:").grid(row=3, column=0, sticky=tk.W, pady=5)
        ttk.Entry(main_frame, textvariable=self.template_file, state="readonly").grid(row=3, column=1, sticky=tk.W+tk.E, pady=5)
        
        # 生成按钮
        btn_frame = ttk.Frame(main_frame)
        btn_frame.grid(row=4, column=0, columnspan=3, pady=10)
        
        ttk.Button(btn_frame, text="生成会话文件", command=self._generate_sessions, 
                  width=20).pack(side=tk.LEFT, padx=10)
        ttk.Button(btn_frame, text="退出", command=self.root.quit, 
                  width=10).pack(side=tk.LEFT, padx=10)
        
        # 状态栏
        self.status_var = tk.StringVar(value="就绪")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
        
        # 设置列权重
        main_frame.columnconfigure(1, weight=1)
        data_frame.columnconfigure(1, weight=1)
        
        # 初始更新模板路径
        self._update_template_path()
    
    def _browse_data_file(self):
        """浏览机器列表文件"""
        filetypes = [("Excel文件", "*.xlsx *.xls"), ("CSV文件", "*.csv"), ("所有文件", "*.*")]
        filename = filedialog.askopenfilename(filetypes=filetypes, title="选择机器列表文件")
        if filename:
            self.data_file.set(filename)
            
            # 如果是Excel文件，自动检测表格名
            if filename.lower().endswith(('.xlsx', '.xls')):
                self._detect_excel_sheets(filename)
    
    def _detect_excel_sheets(self, excel_file):
        """检测Excel文件中的表格名称"""
        try:
            sheet_names, error = get_excel_sheet_names(excel_file)
            
            if error:
                messagebox.showwarning("读取表格警告", f"无法读取Excel表格名: {error}")
                return
            
            if sheet_names and len(sheet_names) > 0:
                # 设置为第一个表格
                self.sheet_name.set(sheet_names[0])
                
                # 如果有多个表格，显示信息
                if len(sheet_names) > 1:
                    sheets_str = ", ".join(sheet_names)
                    messagebox.showinfo("表格信息", f"检测到多个表格: {sheets_str}\n\n已自动选择: {sheet_names[0]}")
        except Exception as e:
            print(f"检测Excel表格名失败: {e}")
    
    def _browse_output_dir(self):
        """浏览输出目录"""
        dirname = filedialog.askdirectory(title="选择输出目录")
        if dirname:
            self.output_dir.set(dirname)
    
    def _browse_template_file(self):
        """浏览模板文件"""
        client = self.client_type.get()
        filetypes = [("所有文件", "*.*")]
        
        if client == "mobaxterm":
            filetypes = [("MobaXterm模板", "*.moba"), ("所有文件", "*.*")]
        elif client == "securecrt":
            filetypes = [("SecureCRT模板", "*.ini"), ("所有文件", "*.*")]
        elif client == "xshell":
            filetypes = [("XShell模板", "*.xsh"), ("所有文件", "*.*")]
        
        filename = filedialog.askopenfilename(filetypes=filetypes, title="选择模板文件")
        if filename:
            self.template_file.set(filename)
    
    def _update_template_path(self, event=None):
        """更新模板路径"""
        client = self.client_type.get()
        template_path = get_template_path(client)
        if template_path:
            self.template_file.set(template_path)
        else:
            self.template_file.set("")
    
    def _download_template(self):
        """下载模板"""
        client = self.client_type.get()
        self.status_var.set(f"正在下载{client}模板...")
        self.root.update_idletasks()
        
        if download_template(client):
            messagebox.showinfo("下载成功", f"已成功下载{client}模板")
            self._update_template_path()
        else:
            messagebox.showerror("下载失败", f"下载{client}模板失败")
        
        self.status_var.set("就绪")
    
    def _create_default_template(self):
        """创建默认模板"""
        client = self.client_type.get()
        self.status_var.set(f"正在创建{client}默认模板...")
        self.root.update_idletasks()
        
        if create_default_template(client):
            messagebox.showinfo("创建成功", f"已成功创建{client}默认模板")
            self._update_template_path()
        else:
            messagebox.showerror("创建失败", f"创建{client}默认模板失败")
        
        self.status_var.set("就绪")
    
    def _generate_sessions(self):
        """生成会话文件"""
        # 参数验证
        if not self.data_file.get():
            messagebox.showerror("错误", "请选择机器列表文件")
            return
        
        if not self.template_file.get():
            messagebox.showerror("错误", "请选择模板文件")
            return
        
        if not os.path.exists(self.data_file.get()):
            messagebox.showerror("错误", "数据文件不存在")
            return
        
        if not os.path.exists(self.template_file.get()):
            messagebox.showerror("错误", "模板文件不存在")
            return
        
        client = self.client_type.get()
        self.status_var.set(f"正在生成{client}会话文件...")
        self.root.update_idletasks()
        
        try:
            # 选择对应的生成器
            generator = None
            if client == "mobaxterm":
                generator = MobaXtermGenerator(self.template_file.get())
            elif client == "securecrt":
                generator = SecureCRTGenerator(self.template_file.get())
            elif client == "xshell":
                generator = XShellGenerator(self.template_file.get())
            
            if generator:
                # 严格验证Excel表格是否存在
                if self.data_file.get().lower().endswith(('.xlsx', '.xls')):
                    is_valid, error_msg = validate_excel_sheet(self.data_file.get(), self.sheet_name.get())
                    
                    if not is_valid:
                        # 提示用户错误并中止操作
                        messagebox.showerror("表格错误", error_msg)
                        self.status_var.set("就绪")
                        return
                
                # 这里是正确的调试代码位置
                sheet_name = self.sheet_name.get()
                print(f"尝试加载表格: {sheet_name}")
                
                # 传递用户指定的输出目录
                success = generator.generate_all_sessions(
                    self.data_file.get(), 
                    output_dir=self.output_dir.get(),
                    sheet_name=self.sheet_name.get()
                )
                
                if success:
                    # 显示实际保存路径
                    output_path = os.path.join(self.output_dir.get(), 'sessions', client)
                    messagebox.showinfo("成功", f"已成功生成{client}会话文件\n保存路径: {output_path}")
                else:
                    messagebox.showerror("错误", f"生成{client}会话文件失败")
            else:
                messagebox.showerror("错误", f"未知的客户端类型: {client}")
        
        except Exception as e:
            messagebox.showerror("错误", f"生成会话文件时发生错误: {e}")
        
        self.status_var.set("就绪")
    
    def _create_machine_list(self, format="xlsx"):
        """创建机器列表模板"""
        output_file = filedialog.asksaveasfilename(
            defaultextension=f".{format}",
            filetypes=[(f"{format.upper()}文件", f"*.{format}"), ("所有文件", "*.*")],
            title="保存机器列表模板",
            initialfile=f"machines_template.{format}"
        )
        
        if output_file:
            self.status_var.set(f"正在创建机器列表模板...")
            self.root.update_idletasks()
            
            if create_machine_list_template(output_file, format):
                messagebox.showinfo("创建成功", f"已成功创建机器列表模板: {output_file}")
                # 自动设置为当前数据文件
                self.data_file.set(output_file)
            else:
                messagebox.showerror("创建失败", "创建机器列表模板失败")
            
            self.status_var.set("就绪")
    
    def _upload_machine_template(self):
        """上传用户的机器列表模板"""
        filetypes = [("Excel文件", "*.xlsx *.xls"), ("CSV文件", "*.csv"), ("所有文件", "*.*")]
        filename = filedialog.askopenfilename(filetypes=filetypes, title="选择机器列表模板文件")
        
        if filename:
            # 获取用户指定的目标位置
            target_file = filedialog.asksaveasfilename(
                defaultextension=os.path.splitext(filename)[1],
                filetypes=filetypes,
                title="保存机器列表模板到",
                initialfile=os.path.basename(filename)
            )
            
            if target_file:
                try:
                    # 复制文件
                    import shutil
                    shutil.copy2(filename, target_file)
                    messagebox.showinfo("上传成功", f"已成功上传机器列表模板: {target_file}")
                    # 自动设置为当前数据文件
                    self.data_file.set(target_file)
                except Exception as e:
                    messagebox.showerror("上传失败", f"上传机器列表模板失败: {e}") 
            self.status_var.set("就绪") 